package com.sec.android.app.myfiles.operation.compress;

import android.content.Context;

import com.sec.android.app.myfiles.module.abstraction.FileRecord;

import java.util.ArrayList;

public class CompressorFactory {

    private static CompressorFactory sInstance = null;

    private Context mContext;

    public static CompressorFactory getInstance(Context context) {
        if (sInstance == null) {
            sInstance = new CompressorFactory(context);
        }
        return sInstance;
    }

    private CompressorFactory(Context context) {
        mContext = context;
    }

    public AbsCompressorImp createCompressor(CompressOptions options) {
        switch (options.mCompressType) {
            case ZIP:
                return new ZipCompressorImp(mContext, options);
            default:
                break;
        }
        return null;
    }

    public static AbsCompressorImp getSupportedCompressor(Context context, ArrayList<FileRecord> srcList, FileRecord dst, CompressOptions options) {
        AbsCompressorImp compressor = null;
        if (options != null) {
            // case of compress.
            if (options.mCompressMode == CompressOptions.CompressMode.COMPRESS) {
                switch (options.mCompressType) {
                    case ZIP:
                        compressor = createZipCompressor(context, srcList, dst, options);
                        break;
                    default:
                        break;
                }
            }
            // case of decompress.
            else {
                if (srcList != null && !srcList.isEmpty() && srcList.get(0) != null) {
                    // decide the compress type from source / destination.
                    FileRecord src = srcList.get(0);
                    if (!src.isDirectory()) {
                        String ext = src.getExt();
                        if ("zip".equalsIgnoreCase(ext)) {
                            options.mCompressType = CompressOptions.CompressType.ZIP;
                            compressor = createZipCompressor(context, srcList, dst, options);
                        }
                    /* add here to another supported compress type.
                    else if ("7z".equalsIgnoreCase(ext)) {
                        options.mCompressType = CompressOptions.CompressType.SVEN_ZIP;
                        // create seven-zip compressor.
                    }
                     */
                    }
                }
            }
        }
        return compressor;
    }

    private static AbsCompressorImp createZipCompressor(Context context, ArrayList<FileRecord> srcList, FileRecord dst, CompressOptions options) {
        // check storage type of src records and create related compressor.
        // only local storage record is available in now.
        // if supported zip compressor is added, add the code to create another
        // compressor.
        switch (options.mCompressMode) {
            case COMPRESS:
            case DECOMPRESS:
                boolean isAvailable = true;
                if (srcList != null && dst != null) {
                    for (FileRecord src : srcList) {
                        if (src.getStorageType() != FileRecord.StorageType.Local
                                && src.getStorageType() != FileRecord.StorageType.FolderTree) {
                            isAvailable = false;
                            break;
                        }
                    }
                    isAvailable = isAvailable && dst.getStorageType() == FileRecord.StorageType.Local;
                    if (isAvailable) {
                        return new ZipCompressorImp(context, options);
                    }
                }
                break;

            case LIST_FILES:
                if (srcList != null && !srcList.isEmpty()) {
                    if (srcList.get(0).getStorageType() == FileRecord.StorageType.Local) {
                        return new ZipCompressorImp(context, options);
                    }
                }
                break;
        }
        return null;
    }
}
